//引入相关模块或插件
const path = require('path');  
const uglify = require('uglifyjs-webpack-plugin');
const htmlPlugin = require('html-webpack-plugin');
const extractTextPlugin = require('extract-text-webpack-plugin');


module.exports = {
    //入口文件的配置项
    entry:{
        //可以配置多个入口文件
        entry: './src/entry.js',
    },


    //出口文件的配置项
    output:{
        //输出的路径
        path: path.resolve(__dirname,'dist'), 
        //输出的文件名称
        //单出口时可以指定输出文件的名称，多出口时直接用[name]代替，输出文件的名称与入口文件名称相同
        filename:'[name].js'     
    },


    //模块打包配置项：通过引入loaders，对指定类型的文件（模块）在打包前应用变换或执行操作，因为Webpack默认只能打包js文件
    module:{
        rules:[
            //对css文件进行解析处理
            {
              test:/\.css$/,
              use:['style-loader',{loader: 'css-loader'}]     
            },
            //对css文件中的图片进行解析处理
            {
                test:/\.(png|jpg|gif)/,
                use:[{
                    loader:'file-loader',
                    options: {
                        outputPath: 'images/'
                    }
                }]
            },
            {
                test: /\.(jsx|js)$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['es2015', 'react']
                        }
                    }
                ]
            }
        ]
    },


    //插件：用于生产模板和各项功能
    plugins:[
        new htmlPlugin({
            minify:{
                removeAttributeQuotes:true
            },
            hash:true,
            template:'./src/index.html'
        }),
    ],


    //配置webpack开发服务功能，相当于搭建一个临时服务器
    devServer:{
        //设置基本目录结构
        contentBase:path.resolve(__dirname,'dist'),
        //服务器的IP地址，可以使用IP地址也可以使用localhost
        host:'localhost',
        //服务器端压缩是否开启
        compress:true,
        //配置服务端口号
        port:1717
    }
}


/*   
  (1)配置入口和出口文件
  (2)配置服务和热更新
  (3)css文件的打包与解析处理
     #1 打包
      在入口文件中引入css文件，如：import css from './css/index.css'
     
     #2 解析处理
      • 安装loaders
       > npm install css-loader style-loader -D

      • 配置loaders
       module:{
           rules:/\.css$/,
           use:['css-loader','style-loader']
       }
      
  (4)css文件中图片的打包与解析处理
      #1 打包
       因为应用在css文件中，所以随着css文件一同打包

      #2 解析处理
       • 安装loaders
        > npm install file-loader url-loader -D
    
       • 配置loaders
        module:{
            rules:[
                {
                    test:/\.(png|jpg|gif)/,
                    use:[
                        {
                            loader:'url-loader',
                            options:{
                                limit:500000,
                                outputPath:'iamges/'
                            }
                        }
                    ]
                }
            ]
        }
       
  (5)css文件的分离与解析处理
    #1 分离
     • 安装插件
      > npm install extract-text-webpack-plugin -D

     • 引入插件
       const extractTextPlugin=require("extract-text-webpack-plugin");

     • 配置插件
       plugins:[
           new extractTextPlugin('/css/index.css')  //其中的'/css/index.css'是分离后的路径
       ]
     
    #2 解析处理
     • 修改loaders配置
        module:{
            rules:[
                {
                    test:/\.css$/,
                    use:extractTextPlugin.extract({
                        fallback:"style-loader",
                        use:"css-loader"
                    })
                }
            ]
        }
        
  (6)css文件中图片的分离与解析处理
     #1 分离
       因为应用在css文件中，所以随着css文件一同分离

     #2 解析处理
       


 
  (7)Less文件的打包和分离
  (8)Sass文件的打包和分离
  (9)自动处理css3属性前缀
     • 安装loaders和插件
     > npm install postcss-loader autoprefixer -D

     • 配置loaders
      //打包的css文件
       module:{
           rules:[
               {
                   test:/\.css$/,
                   use:[
                       {
                           loader:"style-loader"
                       },
                       {
                           loader:"css-loader",
                           options:{
                               modules:true
                           }
                       },
                       {
                           loader:"postcss-loader"
                       }
                   ]
               }
           ]
       }

       //分离的css文件
       module:{
           rules:[
               {
                   test:/\.css$/,
                   use:extractTextPlugin.extract({
                       fallback:"style-loader",
                       use:[
                           {
                               loader:"css-loader",
                               options:{
                                   importLoaders:1
                               } 
                           },
                           "postcss-loader"
                       ]
                   })
               }
           ]
       }
      • 建立postcss.config.js文件
         在项目的根目录下创建一个postcss.config.js文件（和webpack.config.js文件相似），并配置其插件项，如下：
         //postcss.config.js
          module.exports={
              plugins:[
                  require('autoprefixer')
              ]
          }
      

  (10)消除未使用的css
      • 安装插件
       > npm install purifycss-webpack purify-css -D
       
      • 引入插件
       const glob=require('glob');   //用来同步检查html模板
       const purifyCssPlugin=require('purifycss-webpack');
       
      • 配置插件
        plugins:[
            new extractTextPlugin('css/index.css'),
            new purifyCssPlugin({
                paths:glob.sync(path.join(__dirname,'src/*html'))
            });
        ]

    注：这个插件必须配合extract-text-webapck-plugin插件使用


   
  (11)配置JS压缩
     • 安装插件
       uglifyjs-webpack-plugin已经默认集成在webpack中

     • 引入插件
       const uglify=require('uglifyjs-webpack-plugin');

     • 配置插件
       plugins:[
          new uglify()
       ]



  (12)增加babel支持
    • 安装loaders
     > npm install babel-core babel-loader babel-preset-env babel-preset-react -D

    • 配置loaders
     module:{
         rules:[
             {
                 text:/\.(js|jsx)$/,
                 use:[
                     {
                         loader:'babel-loader',
                         options:{
                             preset:['env','react']
                         }
                     }
                 ],
                 exclude:/node_modules/
             }
         ]
     }
    • 创建.babelr文件
      babel可以直接在webpack.config.js中进行配置，但是babel具有非常多的配置项，因此将配置项写在.babelrc文件
    中，更利于可读性,其中，.babelrc文件在项目的根目录中创建
     //.babelrc
       {
           "preset":["env","react"]
       }
     
     //webpack.config.js中配置loaders
      module:{
          rules:[
              {
                  test:/\.(js|jsx)$/,
                  use:[
                      {
                          loader:'babel-loader'
                      }
                  ],
                  exclude:/node_modules/
              }
          ]
      }
  (13)HTML文件的发布
    • 安装插件
     > npm install html-webpack-plugin -D
    
    • 引入插件
     const htmlPlugin=require('html-webpack-plugin');

    • 配置插件
     plugins:[
         new htmlPlugin({
             minify:{
               removeAttributeQuotes:true
             },
             hash:true,
             template:'./src/index.html'
         })
     ]
    
    注：--在src下的原始index.html文件中不需要出现任何的，<style>、<link>、<script>标签
        --通过插件发布index.html文件后，webpack会自动将打包后的js文件通过<script>标签引入
    


  (14)HTML文件中图片的解析处理
     • 安装loaders
      > npm install html-withimg-loader -S

     • 配置loaders
      module:{
          rules:[
              test:/\.(png|jpg|gif)/,
              use:[
                  {
                      loader:'url-loader',
                      options:{
                        limit:500000,
                        outputPath:'iamges/'
                      }
                  },
                  {
                      loader:'html-withimg-loader'
                  }
              ]
          ]
      }      

  (15)打包后如何调试
  (16)实战技巧：开发和生产并行执行
       一个项目中是有开发环境和生产环境的，两个环境的依赖也是不同的，通过npm安装不同环境的依赖如下：
     1)开发环境
       > npm install jquery --save-dev (npm i jquery -D)
      在package.json文件中，开发环境所有的依赖均在"devDependencies"下

     2)生产环境
      > npm install jquery --save(npm i jquery -S)
      在package.json文件中，生产环境所有的所有依赖均在"dependencies"下

     注：依据package.json中的"devDependencies"和"dependencies"可以有以下两种安装：
       //安装全部项目依赖包
        npm install
       
       //安装生产环境依赖包
        npm install --production
 
   
  (17)实战技巧：优雅的打包第三方库/框架
      第三方的库/框架一般都是作为生产环境的依赖存在，所以使用webpack优雅并正确的引入第三方库有以下两种方式：

     1) 在入口文件中直接引入
        • 安装第三方库/框架
        >npm install jquery -S
        • 在入口文件中引用
        //entry.js
        import $ from "jquery"

     2) 通过plugin引入
       • 安装插件
         webpack自带了一个ProvidePlugin插件，无需安装
        
       • 引入插件
         const webpack=require('webpack');

       • 配置插件
         plugins:[
             new webpack.ProvidePlugin({
                 $:"jquery"
             })
         ]
      
      注：两种方式的区别如下：
       --import引入方法：引用后不管在代码中是否使用该库/框架，都会讲该库/框架打包起来，且只会打包一次，缺点是有时会产生代码冗余
       --ProvidePlugin引入方法：相当于在全局进行引入，且只有某个入口文件中真正使用时，才会进行打包，可以避免代码的冗余

  (18)实战技巧：第三方库/框架的抽离
      上节中描述了通过两种方式来优雅的引入第三方库/框架，且通过ProvidePlugin引入时，可以避免代码的冗余，这就是一种优化，但这只
   是在引入第三方库/框架时，优化的第一步，而最好的优化方法就是将第三方库/框架抽离出来，具体如下：
     1) 修改入口文件
        //webpack.config.js
        entry:{
            entry:'./src/entry.js',
            jquery:'jquery',
            vue:'vue'
        }

     2) 安装插件
       webpack自带optimize插件，无需安装

     3) 引入插件
       const webpack=require('webpack');
     
     4) 配置插件
       plugins:[
           new webpack.optimize.CommonsChunkPlugin({
               name:['jquery','vue']                      //name对应入口文件中的名字，例如jquery
               filename:'assets/js/[name].js'             //把文件打包到哪里，是一个路径
               minChunks:2                                //最小打包的文件模块数，这里直接写2
           })
       ]
  (19)实战技巧：静态资源集中输出
    copy-webpack-plugin是专门用于静态资源转移的插件，使用方法如下：
    • 安装插件
     > npm install copy-webpack-plugin -D
    • 引入插件
      const copyWebpackPlugin=require('copy-webpack-plugin');
    • 配置插件
      plugins:[
          new copyWebpackPlugin({
              from:__dirname+'src/public',  //from接要转移的静态资源目录地址
              to:'./public'                 //to接要打包到的文件夹路径，跟随output配置中的目录
          })
      ]
    •
  (20)实战技巧:watch的正确使用方法
  (21)实战技巧：json配置文件的使用
  (22)实战技巧：webpack模块化配置
     主要是对webpack.config.js文件进行模块化配置

*/